<template>
  <el-drawer :append-to-body="true" title="审批人设置" v-model="visible" custom-class="set_promoter" :show-close="false" :size="550" :before-close="saveApprover">
    <div class="drawer_content approver_drawer">
      <el-tabs v-model="activeTab">
        <el-tab-pane label="审批人" name="approver">
          <div class="approver_content approver_card">
            <el-radio-group v-model="approverConfig.assigneeType" class="clear" @change="changeType">
              <el-radio v-for="{ value, label } in assigneeTypes" :key="value" :label="value">{{ label }}</el-radio>
            </el-radio-group>
            <div>
              <el-button type="primary" @click="addApprover" v-if="approverConfig.assigneeType == 'user'">添加/修改成员</el-button>
              <el-button type="primary" @click="addApprover" v-if="approverConfig.assigneeType == 'role'">添加/修改角色</el-button>
              <el-button type="primary" @click="addApprover" v-if="approverConfig.assigneeType == 'depart'">添加/修改部门</el-button>
            </div>
            <p class="selected_list" v-if="['user', 'role', 'depart'].includes(approverConfig.assigneeType)">
              <el-tag v-for="(item, index) in approverConfig.users" :key="index" closable @close="handleRemove('user', item)">{{ operatorMapping.user[item] }}</el-tag>
              <el-tag v-for="(item, index) in approverConfig.departs" :key="index" type="success" closable @close="handleRemove('depart', item)">{{ operatorMapping.depart[item] }}</el-tag>
              <el-tag v-for="(item, index) in approverConfig.roles" :key="index" type="warning" closable @close="handleRemove('role', item)">{{ operatorMapping.role[item] }}</el-tag>
              <el-button v-if="operatorLength != 0" link type="primary" @click="handleClear">清除</el-button>
            </p>
          </div>
          <div class="approver_self approver_card" v-if="approverConfig.assigneeType == 'self'">
            <p>该审批节点设置“发起人自己”后，审批人默认为发起人</p>
          </div>
          <div class="approver_some approver_card" v-if="['user', 'role', 'depart'].includes(approverConfig.assigneeType)">
            <p class="title">多人审批时采用的审批方式</p>
            <el-radio-group v-model="approverConfig.multi" class="clear">
              <el-radio label="sequential">依次审批(按顺序审批)</el-radio>
              <br />
              <el-radio label="single">或签(其中一名审批人通过即可)</el-radio>
              <br />
              <el-radio label="joint">会签(默认须所有审批人同意)</el-radio>
            </el-radio-group>
            <div v-if="approverConfig.multi == 'joint'" class="multi-percent">
              会签审核通过比例(%)
              <el-input-number v-model="approverConfig.multiPercent" :min="1" :max="100" />
            </div>
          </div>
          <!-- 一般泛选审批人时可能出现此种情况,比如指定部门或角色,但是该部门或角色下没有人员 -->
          <div class="approver_empty approver_card" v-if="['role', 'user', 'depart'].includes(approverConfig.assigneeType)">
            <p class="title">审批人为空时</p>
            <el-radio-group v-model="approverConfig.nobody" class="clear">
              <el-radio label="pass">自动通过</el-radio>
              <el-radio label="refuse">自动拒绝</el-radio>
              <br />
              <el-radio label="assign">指定人员</el-radio>
              <el-radio label="admin">转交给流程管理员</el-radio>
            </el-radio-group>
            <div>
              <el-button type="primary" @click="addNobody" v-if="approverConfig.nobody == 'assign'">添加/修改成员</el-button>
            </div>
            <p class="selected_list" v-if="approverConfig.nobody == 'assign'">
              <el-tag v-for="(item, index) in approverConfig.nobodyUsers" :key="index" closable @close="handleRemove('nobody', item)">{{ operatorMapping.user[item] }}</el-tag>
              <el-button v-if="approverConfig.nobodyUsers.length != 0" link type="primary" @click="handleClearNobody">清除</el-button>
            </p>
          </div>
          <div class="approver_back approver_card" v-if="['role', 'user', 'depart', 'self'].includes(approverConfig.assigneeType)">
            <p class="title">审批被驳回时</p>
            <el-form-item label="驳回到指定节点" class="back-choose">
              <el-select v-model="approverConfig.backTo" size="small" placeholder="请选择节点" clearable @change="handleChangeBack">
                <el-option v-for="(item, index) in backNodes" :key="index" :label="item.nodeName" :value="item.id" />
              </el-select>
            </el-form-item>
          </div>
        </el-tab-pane>
        <el-tab-pane label="操作权限" name="operate">
          <el-space fill :size="10" direction="horizontal">
            <div class="opt-item">
              <el-icon :size="32" class="opt-item__icon">
                <CircleCheck />
              </el-icon>
              <div class="opt-item__content">
                <span>同意</span>
                <div class="opt-item__second">审批通过，流转到下一个节点</div>
              </div>
              <el-switch v-model="approverConfig.operations.approved" inline-prompt active-text="开" inactive-text="关" />
            </div>
            <el-divider />
            <div class="opt-item">
              <el-icon :size="32" class="opt-item__icon">
                <CircleClose />
              </el-icon>
              <div class="opt-item__content">
                <span>拒绝</span>
                <div class="opt-item__second">当拒绝任务时，当前任务被终止，并结束整个流程</div>
              </div>
              <el-switch v-model="approverConfig.operations.rejected" inline-prompt active-text="开" inactive-text="关" />
            </div>
            <el-divider />
            <div class="opt-item">
              <el-icon :size="32" class="opt-item__icon">
                <Back />
              </el-icon>
              <div class="opt-item__content">
                <span>驳回</span>
                <div class="opt-item__second">当前任务将回退至特定历史任务节点（必须指定驳回节点）</div>
              </div>
              <el-switch v-model="approverConfig.operations.rollback" :disabled="!approverConfig.backTo" inline-prompt active-text="开" inactive-text="关" />
            </div>
          </el-space>
        </el-tab-pane>
      </el-tabs>
    </div>
    <template #footer>
      <div class="drawer-footer">
        <el-button type="primary" @click="saveApprover">确 定</el-button>
        <el-button @click="closeDrawer">取 消</el-button>
      </div>
    </template>
    <EmployeesDialog v-model:visible="approverVisible" :users="checkedUserList" :departs="checkedDepartList" :roles="checkedRoleList" :assigneeType="approverConfig.assigneeType" @change="sureApprover" />
    <EmployeesDialog v-model:visible="nobodyVisible" :users="nobodyUsers" assigneeType="user" @change="sureNobody" />
  </el-drawer>
</template>

<script setup>
import { ref, watch, computed } from 'vue'
import { assigneeTypes } from '@/utils/flowConst'
import { useStore } from 'vuex'
import { CircleCheck, CircleClose, Back } from '@element-plus/icons-vue'
import $func from '@/utils/flow'
import { ElMessage } from 'element-plus'

let store = useStore()
const operatorMapping = computed(() => store.state.flow.operatorMapping)
const nodeConfig = computed(() => store.state.flow.nodeConfig)
let approverDrawer = computed(() => store.state.flow.approverDrawer)
let approverConfig1 = computed(() => store.state.flow.approverConfig1) // 审批人配置
let approverConfig = ref({}) // 审批人配置副本
const activeTab = ref('approver')
let operatorLength = computed(() => approverConfig.value.users?.length + approverConfig.value.departs?.length + approverConfig.value.roles?.length) // 已选择人员数量
let visible = computed({
  get() {
    return approverDrawer.value
  },
  set() {
    closeDrawer()
  }
})
watch(approverConfig1, val => {
  approverConfig.value = val.value
})

const changeType = () => {
  approverConfig.value.users = []
  approverConfig.value.departs = []
  approverConfig.value.roles = []
  approverConfig.value.multi = 'single'
  approverConfig.value.nobody = 'pass'
  approverConfig.value.nobodyUsers = []
}
// 已选择操作人员
let approverVisible = ref(false)
const checkedUserList = ref([])
const checkedDepartList = ref([])
const checkedRoleList = ref([])
const addApprover = () => {
  checkedUserList.value = approverConfig.value.users
  checkedDepartList.value = approverConfig.value.departs
  checkedRoleList.value = approverConfig.value.roles
  approverVisible.value = true
}

// 移除已选择
const handleRemove = (type, id) => {
  if (type == 'user') {
    approverConfig.value.users = approverConfig.value.users.filter(item => item != id)
  } else if (type == 'depart') {
    approverConfig.value.departs = approverConfig.value.departs.filter(item => item != id)
  } else if (type == 'role') {
    approverConfig.value.roles = approverConfig.value.roles.filter(item => item != id)
  } else if (type == 'nobody') {
    approverConfig.value.nobodyUsers = approverConfig.value.nobodyUsers.filter(item => item != id)
  }
}

// 清空已选择
const handleClear = () => {
  approverConfig.value.users = []
  approverConfig.value.departs = []
  approverConfig.value.roles = []
}

const sureApprover = (users, departs, roles) => {
  approverConfig.value.users = users
  approverConfig.value.departs = departs
  approverConfig.value.roles = roles
  approverVisible.value = false
}

const saveApprover = () => {
  approverConfig.value.error = !$func.setApproverStr(approverConfig.value)
  store.commit('flow/setApproverConfig', {
    value: approverConfig.value,
    flag: true,
    id: approverConfig1.value.id
  })
  closeDrawer()
}
const closeDrawer = () => {
  store.commit('flow/setApprover', false)
}

/******************审批人为空时***************/
const nobodyVisible = ref(false)
const nobodyUsers = ref([])

const addNobody = () => {
  nobodyUsers.value = approverConfig.value.nobodyUsers
  nobodyVisible.value = true
}

const sureNobody = users => {
  approverConfig.value.nobodyUsers = users
  nobodyVisible.value = false
}

const handleClearNobody = () => {
  approverConfig.value.nobodyUsers = []
}
/************************驳回节点选择***************/
const backNodes = ref([])
function findNodesById(jsonObj, targetId) {
  let result = []
  function traverse(node, id) {
    if (node.id === id) {
      return true
    }
    if (node.childNode) {
      if (traverse(node.childNode, id)) {
        if (node.type === 'approval') {
          result.push(node)
        }
        return true
      }
    }
    if (node.conditionNodes) {
      for (let i = 0; i < node.conditionNodes.length; i++) {
        if (traverse(node.conditionNodes[i], id)) {
          if (node.type === 'approval') {
            result.push(node)
          }
          return true
        }
      }
    }
    return false
  }
  traverse(jsonObj, targetId)
  result.reverse()
  return result
}

watch(
  visible,
  val => {
    if (!val) return
    backNodes.value = findNodesById(nodeConfig.value, approverConfig1.value.value.id)
  },
  { deep: true }
)

// 清除驳回节点时，关闭驳回权限并禁用
const handleChangeBack = (val) => {
  if(!val){
    ElMessage.warning('未指定驳回节点，已关闭驳回操作权限')
    approverConfig.value.operations.rollback = false
  } else {
    ElMessage.success('已默认开启驳回操作权限')
    approverConfig.value.operations.rollback = true
  }
}
</script>

<style lang="scss" scoped>
.set_promoter {
  .approver_drawer {
    .approver_card {
      padding-top: 20px;
      border-bottom: 1px solid #f2f2f2;
      .title {
        line-height: 19px;
        font-size: 14px;
        margin-bottom: 14px;
      }
    }
    .approver_card:last-child {
      border-bottom: none;
    }
    .approver_content,
    .approver_empty {
      .el-button:not(.is-link) {
        margin-bottom: 20px;
      }
    }
    .approver_empty,
    .approver_content,
    .approver_some {
      .el-radio-group {
        display: unset;
      }
      .el-radio {
        width: 27%;
        margin-bottom: 20px;
        height: 16px;
      }
      .multi-percent {
        margin-bottom: 20px;
        font-size: 14px;
        color: #333333;
      }
    }
    .approver_self {
      padding-bottom: 20px;
    }
    .approver_back .back-choose {
      display: flex;
      align-items: center;
      .el-select {
        margin-left: 10px;
      }
    }
  }
  .opt-item {
    display: flex;
    align-items: center;

    .opt-item__icon {
      background: $mainColor;
      color: #fff;
      border-radius: 7px;
      padding: 3px;
    }

    .opt-item__content {
      box-sizing: border-box;
      flex: 1;
      margin-left: 20px;
      font-size: 12px;

      .opt-item__second {
        margin-top: 3px;
        font-size: 12px;
        color: #aaaaaa;
      }
    }
  }
}
</style>
